﻿// -----------------------------------------------------------------------
// <copyright file="RemoveOnlyObservableCollection.cs" company="">
//      Copyright 2012 Samuel Englard
//      
//      Microsoft Reciprocal License (Ms-RL)
// 
//      This license governs use of the accompanying software. If you use the software, you accept this license. If you do 
//      not accept the license, do not use the software.
// 
//      1. Definitions
// 
//      The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under 
//      U.S. copyright law.
// 
//      A "contribution" is the original software, or any additions or changes to the software.
// 
//      A "contributor" is any person that distributes its contribution under this license.
// 
//      "Licensed patents" are a contributor's patent claims that read directly on its contribution.
// 
//      2. Grant of Rights
// 
//      (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in 
//      section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its 
//      contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works 
//      that you create.
// 
//      (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 
//      3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, 
//      have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or 
//      derivative works of the contribution in the software.
// 
//      3. Conditions and Limitations
// 
//      (A) Reciprocal Grants- For any file you distribute that contains code from the software (in source code or binary 
//      format), you must provide recipients the source code to that file along with a copy of this license, which license 
//      will govern that file. You may license other files that are entirely your own work and do not contain code from the
//      software under any terms you choose.
// 
//      (B) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
// 
//      (C) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, 
//      your patent license from such contributor to the software ends automatically.
// 
//      (D) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution 
//      notices that are present in the software.
// 
//      (E) If you distribute any portion of the software in source code form, you may do so only under this license by 
//      including a complete copy of this license with your distribution. If you distribute any portion of the software in 
//      compiled or object code form, you may only do so under a license that complies with this license.
// 
//      (F) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, 
//      guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot 
//      change. To the extent permitted under your local laws, the contributors exclude the implied warranties of 
//      merchantability, fitness for a particular purpose and non-infringement.
//
// </copyright>
// -----------------------------------------------------------------------

namespace System.Collections.ObjectModel
{
    /// <summary>
    ///     Represents a <see cref="System.Collections.ObjectModel.ObservableCollection{T}"/> that items can only be removed from, not added.
    /// </summary>
    /// <typeparam name="T">
    ///     The type of elements in the collection.
    /// </typeparam>
    [Serializable]
    public class RemoveOnlyObservableCollection<T> : ReadOnlyObservableCollection<T>
    {
        private ObservableCollection<T> list;

        /// <summary>
        ///     Initializes a new instance of the <see cref="System.Collections.ObjectModel.RemoveOnlyObservableCollection{T}"/> class that serves as a wrapper around the specified <see cref="System.Collections.ObjectModel.ObservableCollection{T}"/>.
        /// </summary>
        /// <param name="list">
        ///     The <see cref="System.Collections.ObjectModel.ObservableCollection{T}"/> with which to create this instance of the <see cref="System.Collections.ObjectModel.RemoveOnlyObservableCollection{T}"/> class.
        /// </param>
        public RemoveOnlyObservableCollection(ObservableCollection<T> list) : base(list)
        {
            this.list = list;
        }

        /// <summary>
        ///     Removes all elements from the <see cref="System.Collections.ObjectModel.RemoveOnlyObservableCollection{T}"/>.
        /// </summary>
        public void Clear()
        {
            list.Clear();
        }

        /// <summary>
        ///     Removes the first occurrence of a specific object from the <see cref="System.Collections.ObjectModel.RemoveOnlyObservableCollection{T}"/>.
        /// </summary>
        /// <param name="item">
        ///     <para>
        ///         The object to remove from the <see cref="System.Collections.ObjectModel.RemoveOnlyObservableCollection{T}"/>.
        ///     </para>
        ///     <para>
        ///         The value can be null for reference types.    
        ///     </para>
        /// </param>
        /// <returns>
        ///     <c>true</c> if item is successfully removed; otherwise, <c>false</c>. This method also returns <c>false</c> if item was not found in the <see cref="System.Collections.ObjectModel.RemoveOnlyObservableCollection{T}"/>.
        /// </returns>
        public bool Remove(T item)
        {
            return list.Remove(item);
        }

        /// <summary>
        ///     Removes the element at the specified index of the <see cref="System.Collections.ObjectModel.RemoveOnlyObservableCollection{T}"/>.
        /// </summary>
        /// <param name="index">
        ///     The zero-based index of the element to remove.
        /// </param>
        /// <exception cref="System.ArgumentOutOfRangeException">
        ///     <paramref name="index"/> is less than zero.-or-<paramref name="index"/> is equal to or greater than <see cref="System.Collections.ObjectModel.RemoveOnlyObservableCollection{T}.Count"/>.
        /// </exception>
        public void RemoveAt(int index)
        {
            if ((index < 0) || (index >= Count))
            {
                throw new ArgumentOutOfRangeException("index", index, "index is less than zero.-or-index is equal to or greater than System.Collections.ObjectModel.Collection<T>.Count.");
            }

            list.RemoveAt(index);
        }
    }
}
